"""
Hit the object minigame.

A number of objects are on the screen, the user has to click on the 'bad'
objects but not the 'good' ones. The objects may move around.
"""

#  Copyright 2010 Nick Ryder.

#  This file is part of Minigame Mayhem.

#  Minigame Mayhem is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.

#  Minigame Mayhem is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.

#  You should have received a copy of the GNU General Public License
#  along with Minigame Mayhem.  If not, see <http://www.gnu.org/licenses/>.


import pygame
import os
from pygame.locals import *
import time
import sys
import random
import os
cwd = os.getcwd()
corepath = os.path.split(cwd)[0]
corepath = os.path.join(corepath, "core")
sys.path.append(corepath)
import minigame
import spritesheet

class TargetObject:
   "Targets that move around the screen."

   def __init__(self, name=""):
      self.name = name
      self.hit = False        # Bool: Has the target been hit?
      self.hittime = None     # float: time that target was hit
      self.dead = False       # Bool: Is the target dead?
      self.deathtime = 3    # Time after being hit that target dies
      self.image = None
      self.rect = None
      self.nonhitImage = None
      self.hitRect = None
      self.hitImage = None
      self.imageChanged = False
      self.background = None

   def set_images(self, image, imagehit):
      self.nonhitImage = image
      self.hitImage = imagehit
      self.rect = self.hitImage.get_rect()
      width = int(0.8 * self.rect.width)
      height = int(0.8 * self.rect.height)
      self.hitRect = pygame.Rect((0, 0), (width, height))
      self.background = pygame.Surface(self.rect.size)

   def set_backgroundcolour(self, backgroundcolour):
      self.background.fill(backgroundcolour)

   def position(self, center):
      "Set center of target."
      self.rect.center = center
      self.hitRect.center = center

   def update(self):
      "Move object and update image if needed."
      # select image
      if self.hit != True:
         self.image = self.nonhitImage
      else:
         self.image = self.hitImage
         if self.dead != True:
            now = time.time()
            if (now - self.hittime) > self.deathtime:
               self.dead = True

   def draw(self, screen):
      "Draw image go screen."
      screen.blit(self.background, self.rect)
      if not self.dead:
         screen.blit(self.image, self.rect)

   def checkhit(self, pos):
      "Determine if target is hit given click position."
      if self.hitRect.collidepoint(pos):
         if self.hit == False:
            self.hit = True
            self.hittime = time.time()

class HitTheObjectsMinigame(minigame.Minigame):

   def __init__(self, screen, level):
      minigame.Minigame.__init__(self, screen, level)
      self.images = []
      self.targets = []
      self.gametime = 10
      self.backgroundcolour = (98, 103, 77)
      self.background = pygame.Surface((self.screen.get_width(), self.screen.get_height()))
      self.background.fill(self.backgroundcolour)
      self.screen.blit(self.background, (0, 0))
      pygame.display.flip()

   def load(self):
      sprites = spritesheet.SpriteSheet(os.path.join(self.datapath, "hitsprites.bmp"))
      height = 50
      width = 50
      names = ["guy", "ninja", "balloon"]
      for a in range(3):
         images = []
         for b in range(2):
            rect = pygame.Rect(b * (width + 1) + 1, a * (height + 1) + 1, width, height)
            images.append(sprites.get_image(rect, -1))
         self.images.append(images)
      for a in range(len(self.images)):
         self.targets.append(TargetObject(names[a]))
         self.targets[-1].set_images(self.images[a][0], self.images[a][1])
         self.targets[-1].set_backgroundcolour(self.backgroundcolour)

   def start(self):
      width = 50
      height = 50
      for target in self.targets:
         centerx = random.randint(0 + width/2, self.screen.get_width() - width/2)
         centery = random.randint(0 + height/2, self.screen.get_height() - height/2)
         target.position((centerx, centery))

   def main(self):
      infofont = pygame.font.Font(None, 30)
      timesurf = pygame.Surface(infofont.size("Time Left: 30s"))
      timesurf.fill(self.backgroundcolour)
      timerect = timesurf.get_rect(right = self.screen.get_width(),
         bottom = self.screen.get_height())
      starttime = time.time()
      currenttime = time.time()
      timeleft = self.gametime - (currenttime - starttime)
      while timeleft > 0:
         currenttime = time.time()
         timeleft = self.gametime - (currenttime - starttime)
         timemsg = "Time left: %ds" % (timeleft+ 1)
         timemsg = infofont.render(timemsg, 1, (0, 0, 0))
         self.screen.blit(timesurf, timerect)
         self.screen.blit(timemsg, timerect)
         for event in pygame.event.get():
            if event.type == QUIT:
               sys.exit()
            elif event.type == KEYDOWN:
               if event.key == K_ESCAPE:
                  sys.exit()
            elif event.type == MOUSEBUTTONDOWN:
               x, y = pygame.mouse.get_pos()
               for target in self.targets:
                  target.checkhit((x, y)) 
         for target in self.targets:
            target.update()
            #self.screen.blit(self.background, target.rect)
            target.draw(self.screen)
         pygame.display.flip()

   def finish(self):
      win = True
      for target in self.targets:
         if target.hit == False:
            win = False
      if win:
         print "You win!"
      else:
         print "You lose!"
      
if __name__ == "__main__":
   random.seed()
   pygame.init()
   screen = pygame.display.set_mode((800, 600))
   pygame.display.set_caption("Hit The Object Minigame")
   if len(sys.argv) == 2:
      try:
         level = int(sys.argv[1])
      except ValueError:
         print "Argument must be level (int)"
         sys.exit()
   else:
      level = random.randint(0, 5)
   hm = HitTheObjectsMinigame(screen, level)
   hm.run()
